﻿#region

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using ThuySan.Bussiness;
using ThuySan.Models;
using System.Net.Mail;
using System.Configuration;

#endregion

namespace ThuySan.Controllers
{
    public class HomeController : Controller
    {
        private readonly UnitOfWork _unitOfWork = new UnitOfWork();

        //
        // GET: /Home/

        public ActionResult Index(int numberProducts = 6)
        {
            numberProducts = int.Parse(_unitOfWork.SettingRepository.Select(c => c.Name.Equals("NumberInHome")).FirstOrDefault().Value);
            var query = _unitOfWork.ProductRepository.Select(c => c.IsVisibled == true, c => c.LastModified, ListSortDirection.Descending).Select(c => new
            {
                Category = c.Category.PageUrl,
                c.ProductId,
                c.Name,
                c.PageUrl,
                c.LastModified,
                c.Description,
                c.AvatarImage,
                c.Price
            }).Skip(0).Take(numberProducts);
            List<dynamic> prods = new List<dynamic>();
            foreach (var item in query)
            {
                dynamic obj = new DynamicViewDataDictionary();
                obj.Category = item.Category;
                obj.ProductId = item.ProductId;
                obj.Name = item.Name;
                obj.PageUrl = item.PageUrl;
                obj.LastModified = item.LastModified;
                obj.Description = item.Description;
                obj.AvatarImage = item.AvatarImage;
                obj.Price = item.Price;
                prods.Add(obj);
            }
            return View(prods);
        }

        public ActionResult BrowseCategory(int categoryId, string type, string otype, string n, string page)
        {
            ViewBag.Category = _unitOfWork.CategoryRepository.SelectbyId(categoryId);
            IQueryable<Product> q1 = _unitOfWork.ProductRepository.Select(c => c.CategoryId == categoryId && c.IsVisibled == true, "Category");
            if ("price".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                q1 = "desc".Equals(otype, StringComparison.InvariantCultureIgnoreCase)
                             ? q1.OrderByDescending(c => c.IsReduced == true
                                                                 ? c.PromotionalPrice
                                                                 : c.Price)
                             : q1.OrderBy(c => c.IsReduced == true
                                                       ? c.PromotionalPrice
                                                       : c.Price);
            else if ("name".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                q1 = "desc".Equals(otype, StringComparison.InvariantCultureIgnoreCase)
                             ? q1.OrderByDescending(c => c.Name)
                             : q1.OrderBy(c => c.Name);
            else if ("status".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                q1 = q1.OrderByDescending(c => c.Status);
            else
                q1 = q1.OrderBy(c => c.Priority).ThenByDescending(c => c.LastModified);
            ViewBag.Count = q1.Count();
            int size,
                pNumber;
            if (!int.TryParse(n, out size))
                size = 9;
            ViewBag.PageSize = size;
            if (size < 9)
                size = 9; // default to show 9 items on page
            if (!int.TryParse(page, out pNumber))
                pNumber = 1;
            if (pNumber <= 0)
                pNumber = 1;
            q1 = q1.Skip((pNumber - 1) * size).Take(size);
            return View(q1);
        }

        public ActionResult BrowseTag(int tagId, string type, string otype, string n, string page)
        {
            Tag tag = _unitOfWork.TagRepository.SelectbyId(tagId);
            if (tag != null)
            {
                if (tag.IsStaticContent == true)
                {
                    dynamic obj = new DynamicViewDataDictionary();
                    obj.Name = tag.Name;
                    obj.Description = tag.Description;
                    obj.Detail = tag.Detail;
                    return View("ShowStaticContent", obj);
                }
                else
                {
                    ViewBag.TagName = _unitOfWork.TagRepository.Select(c => c.TagId == tagId).FirstOrDefault().Name;
                    var q1 = _unitOfWork.ProductTagRepository.Select(c => c.TagId == tagId && c.Product.IsVisibled == true).Select(c => new
                    {
                        c.Product.ProductId,
                        c.Product.Name,
                        Category = c.Product.Category.PageUrl,
                        c.Product.IsReduced,
                        c.Product.PromotionalPrice,
                        c.Product.Price,
                        c.Product.PageUrl,
                        c.Product.Status,
                        c.Product.Priority,
                        c.Product.LastModified,
                        c.Product.AvatarImage,
                        c.Product.Description
                    });
                    if ("price".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                        q1 = "desc".Equals(otype, StringComparison.InvariantCultureIgnoreCase)
                                     ? q1.OrderByDescending(c => c.IsReduced == true
                                                                         ? c.PromotionalPrice
                                                                         : c.Price)
                                     : q1.OrderBy(c => c.IsReduced == true
                                                               ? c.PromotionalPrice
                                                               : c.Price);
                    else if ("name".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                        q1 = "desc".Equals(otype, StringComparison.InvariantCultureIgnoreCase)
                                     ? q1.OrderByDescending(c => c.Name)
                                     : q1.OrderBy(c => c.Name);
                    else if ("status".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                        q1 = q1.OrderByDescending(c => c.Status);
                    else
                        q1 = q1.OrderBy(c => c.Priority).ThenByDescending(c => c.LastModified);
                    ViewBag.Count = q1.Count();
                    int size,
                        pNumber;
                    if (!int.TryParse(n, out size))
                        size = 12;
                    if (size < 9)
                        size = 9;
                    if (!int.TryParse(page, out pNumber))
                        pNumber = 1;
                    if (pNumber < 0)
                        pNumber = 1;
                    q1 = q1.Skip((pNumber - 1) * size).Take(size);
                    List<dynamic> list = new List<dynamic>();
                    foreach (var item in q1)
                    {
                        dynamic obj = new DynamicViewDataDictionary();
                        obj.ProductId = item.ProductId;
                        obj.Name = item.Name;
                        obj.Category = item.Category;
                        obj.IsReduced = item.IsReduced;
                        obj.PromotionalPrice = item.PromotionalPrice;
                        obj.Price = item.Price;
                        obj.PageUrl = item.PageUrl;
                        obj.Status = item.Status;
                        obj.Priority = item.Priority;
                        obj.LastModified = item.LastModified;
                        obj.AvatarImage = item.AvatarImage;
                        obj.Description = item.Description;
                        list.Add(obj);
                    }
                    return View(list);
                    //IOrderedQueryable<Product> query = _unitOfWork.ProductTagRepository.Select(c => c.TagId == tagId).Select(c => c.Product).Where(c => c.IsVisibled == true)
                    //    .OrderBy(c => c.Priority ?? int.MaxValue).OrderByDescending(c => c.LastModified);
                    //return View(query.ToList());
                }
            }
            else
            {
                return null;
            }
        }

        public ActionResult TypeTagList()
        {
            var query = _unitOfWork.TagRepository.Select(c => c.IsLeftColumn == true && (c.IsStaticContent == null || c.IsStaticContent == false)).SelectMany(c => c.ProductTags.DefaultIfEmpty(), (c, v) => new
            {
                Tag = new
                {
                    c.TagId,
                    c.Name,
                    c.Avatar,
                    c.Description,
                    c.PageUrl
                },
                v.Product.IsVisibled
            }).GroupBy(c => c.Tag).Select(c => new
            {
                c.Key.TagId,
                c.Key.Name,
                c.Key.PageUrl,
                c.Key.Avatar,
                c.Key.Description,
                NumberProduct = c.Count(v => v.IsVisibled ?? false)
            });
            List<dynamic> list = new List<dynamic>();
            foreach (var item in query)
            {
                dynamic obj = new DynamicViewDataDictionary();
                obj.TagId = item.TagId;
                obj.Name = item.Name;
                obj.PageUrl = item.PageUrl;
                obj.Description = item.Description;
                obj.Avatar = item.Avatar;
                obj.NumberProduct = item.NumberProduct;
                list.Add(obj);
            }

            string currentPage = Path.GetFileName(Request.Path);
            if (currentPage.Equals("phan-loai.html"))
            {
                return View("TypeTagList", list);
            }
            return PartialView("TypeTagModule", list);
        }

        public ActionResult ReducedPriced(string type, string otype, string n, string page)
        {
            IQueryable<Product> q1 = _unitOfWork.ProductRepository.Select(c => c.IsReduced == true && c.IsVisibled == true, "Category");
            if ("price".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                q1 = "desc".Equals(otype, StringComparison.InvariantCultureIgnoreCase)
                             ? q1.OrderByDescending(c => c.IsReduced == true
                                                                 ? c.PromotionalPrice
                                                                 : c.Price)
                             : q1.OrderBy(c => c.IsReduced == true
                                                       ? c.PromotionalPrice
                                                       : c.Price);
            else if ("name".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                q1 = "desc".Equals(otype, StringComparison.InvariantCultureIgnoreCase)
                             ? q1.OrderByDescending(c => c.Name)
                             : q1.OrderBy(c => c.Name);
            else if ("status".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                q1 = q1.OrderByDescending(c => c.Status);
            else
                q1 = q1.OrderBy(c => c.Priority).ThenByDescending(c => c.LastModified);
            ViewBag.Count = q1.Count();
            int size,
                pNumber;
            if (!int.TryParse(n, out size))
                size = 12;
            if (size < 9)
                size = 9;
            if (!int.TryParse(page, out pNumber))
                pNumber = 1;
            if (pNumber < 0)
                pNumber = 1;
            q1 = q1.Skip((pNumber - 1) * size).Take(size);
            return View(q1);
        }

        public ActionResult Search(string q, string type, string otype, string n, string page)
        {
            var query = _unitOfWork.ProductRepository.Select(c => c.IsVisibled == true && (c.Name.Contains(q) || c.Description.Contains(q))).Select(c => new
            {
                Id = c.ProductId,
                c.Name,
                c.Description,
                Url1 = c.PageUrl,
                Url2 = c.Category.PageUrl,
                Image = c.AvatarImage,
                Type = 1
            });
            query = query.Union(_unitOfWork.CategoryRepository.Select(c => (c.Name.Contains(q) || c.Description.Contains(q))).Select(c => new
            {
                Id = c.CategoryId,
                c.Name,
                c.Description,
                Url1 = c.PageUrl,
                Url2 = "",
                Image = "",
                Type = 2
            }));
            query = query.Union(_unitOfWork.TagRepository.Select(c => (c.Name.Contains(q) || c.Description.Contains(q))).Select(c => new
            {
                Id = c.TagId,
                c.Name,
                c.Description,
                Url1 = c.PageUrl,
                Url2 = "",
                Image = "",
                Type = 3
            }));
            if ("name".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                query = "desc".Equals(otype, StringComparison.InvariantCultureIgnoreCase)
                                ? query.OrderByDescending(c => c.Name)
                                : query.OrderBy(c => c.Name);
            else
                query = query.OrderBy(c => c.Name);

            ViewBag.Count = query.Count();
            int size,
                pNumber;
            if (!int.TryParse(n, out size))
                size = 9;
            ViewBag.PageSize = size;
            if (!int.TryParse(page, out pNumber))
                pNumber = 1;
            if (pNumber < 0)
                pNumber = 1;
            query = query.Skip((pNumber - 1) * size).Take(size);
            List<DynamicViewDataDictionary> result = new List<DynamicViewDataDictionary>();
            foreach (var item in query)
            {
                dynamic obj = new DynamicViewDataDictionary();
                obj.Id = item.Id;
                obj.Name = item.Name;
                obj.Description = item.Description;
                obj.Url1 = item.Url1;
                obj.Url2 = item.Url2;
                obj.Type = item.Type;
                result.Add(obj);
            }
            return View(result);
        }

        public ActionResult Contact()
        {
            return View(new ContactModel());
        }

        [HttpPost]
        public ActionResult Contact(ContactModel contact)
        {
            
            if (ModelState.IsValid)
            {
                EmailTemplate template = _unitOfWork.EmailTemplateRepository.Select().FirstOrDefault();
                template.Body.Replace("%%EMAIL%%", contact.Email);
                template.Body.Replace("%%MESSAGE%%", contact.Message);
                if (template != null)
                {
                    try
                    {
                        var mailMessage = new MailMessage { IsBodyHtml = true, Body = template.Body, Subject = template.Subject };
                        mailMessage.To.Add(ConfigurationManager.AppSettings["MailTo"]);
                        var user = _unitOfWork.UserRepository.Select().Select(c => c.Email);
                        bool first = true;
                        foreach (var item in user)
                        {
                            if (first)
                            {
                                mailMessage.To.Add(new System.Net.Mail.MailAddress(item));
                                first = false;
                            }
                            else
                            {
                                mailMessage.CC.Add(new System.Net.Mail.MailAddress(item));
                            }
                        }
                        if (!first)
                        {
                            var client = new SmtpClient();
                            client.Send(mailMessage);
                        }
                        ViewBag.Completed = true;
                    }
                    catch (Exception)
                    {
                    }
                }
            }
            ViewBag.Completed = true;
            return View(contact);
        }

        public ActionResult NewProducts(string type, string otype, string n, string page)
        {
            DateTime lessDate = DateTime.Now.AddDays(-7);
            IQueryable<Product> q1 = _unitOfWork.ProductRepository.Select(c => c.IsVisibled == true && c.LastModified > lessDate, "Category");
            if ("price".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                q1 = "desc".Equals(otype, StringComparison.InvariantCultureIgnoreCase)
                             ? q1.OrderByDescending(c => c.IsReduced == true
                                                                 ? c.PromotionalPrice
                                                                 : c.Price)
                             : q1.OrderBy(c => c.IsReduced == true
                                                       ? c.PromotionalPrice
                                                       : c.Price);
            else if ("name".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                q1 = "desc".Equals(otype, StringComparison.InvariantCultureIgnoreCase)
                             ? q1.OrderByDescending(c => c.Name)
                             : q1.OrderBy(c => c.Name);
            else if ("status".Equals(type, StringComparison.InvariantCultureIgnoreCase))
                q1 = q1.OrderByDescending(c => c.Status);
            else
                q1 = q1.OrderByDescending(c => c.LastModified);
            ViewBag.Count = q1.Count();
            int size,
                pNumber;
            if (!int.TryParse(n, out size))
                size = 9;
            ViewBag.PageSize = size;
            if (size < 9)
                size = 9; // default to show 9 items on page
            if (!int.TryParse(page, out pNumber))
                pNumber = 1;
            if (pNumber <= 0)
                pNumber = 1;
            q1 = q1.Skip((pNumber - 1) * size).Take(size);
            return View(q1);
        }
    }
}
